#include <stdlib.h>		/* for malloc */
#include <string.h>		/* for strcmp, strlen and strcpy */
#include <stdio.h>		/* for printf */
#include "hoc.h"		/* for Symbol_t and execerror */
#include "y.tab.h"		/* for symbol types */

/* Prototype functions */
void *emalloc(unsigned int);

/* Global Variables */
Symbol_t* symlist = NULL;	/* Symbol table; linked list */


/* Find str in symbol table */
Symbol_t* lookup(const char *ptr_cstr) {
	Symbol_t* ptr_sym;

	for ( ptr_sym = symlist; ptr_sym != NULL; ptr_sym = ptr_sym->ptr_next ) {
		if ( strcmp( ptr_sym->ptr_cname, ptr_cstr) == 0 ) {
			return ptr_sym;
		}
	}
	return NULL;	/* NULL ==> Not Found */
}

/* Install cname NUMBER in symbol table */
Symbol_t* install(const char *ptr_cname, int itype, int datatype, double value) {
	/*printf("Installing %s value %g with datatype %d itype %d \n",ptr_cname, value,datatype,itype);*/
	Symbol_t* ptr_sym;

	/* Reserve space for new node */
	ptr_sym = (Symbol_t*) emalloc(sizeof(Symbol_t));
	ptr_sym->ptr_cname = (char *) emalloc(strlen(ptr_cname)+1);	/* +1 for '\0' */

	/* Make the new node */
	strcpy(ptr_sym->ptr_cname, ptr_cname);
	ptr_sym->itype = itype;
	ptr_sym->datatype = datatype;
	
	/* Install correct numeric value */
	switch(datatype)
	{
	case INT:
		ptr_sym->u.ival = (int)value;
		/*printf("INT set ival to %d\n",ptr_sym->u.ival);*/
		break;
	case CHAR:
		ptr_sym->u.cval = (char)value;
		/*printf("CHAR set cval to %c\n",ptr_sym->u.cval);*/
		break;
	case BOOLEAN:
		ptr_sym->u.bval = (bool)value;
		/*printf("BOOLEAN set bval to %d\n",ptr_sym->u.bval);*/
		break;
	case FLOAT:
	default:
		ptr_sym->u.dval = value;
		/*printf("FLOAT set ival to %g\n",ptr_sym->u.dval);*/
		break;

		
	}


	/* Place the new node at the front of the list */
	ptr_sym->ptr_next = symlist;
	symlist = ptr_sym;

	return ptr_sym;
}

/* Check return from malloc */
void *emalloc(unsigned int isize) {
	void *ptr;
	ptr = malloc(isize);
	if ( ptr == NULL ) {
		execerror("out of memory", NULL);
	}
	return ptr;
}
